struct Point { x: i32, y: i32, z: i32 }

fn main() {
    // 对于值来说，是可以mut也可以imutable的
    // 对于引用来说，也是一样的，所以这两个限定相同
    let mut point = Point { x: 0, y: 0, z: 0 };

    // 借用，只读
    // 引用的访问也和值相同
    // 那在什么情况下，才使用* 解引用呢？目前看来结构体不需要
    // 结构体中存储引用的时候要指定生命周期
    let borrowed_point = &point;
    let another_borrow = &point;

    // Data can be accessed via the re
    //
    // ferences and the original owner
    println!("Point has coordinates: ({}, {}, {})",
                borrowed_point.x, another_borrow.y, point.z);

    // Error! Can't borrow `point` as mutable because it's currently
    // borrowed as immutable.
    // let mutable_borrow = &mut point;
    // TODO ^ Try uncommenting this line
    // 可变引用和不可变引用不能共存，除非作为最后一个使用者，不然就会引出来问题
    // Box<T>是一个引用，所以要取其值，要解引用


    // The borrowed values are used again here
    println!("Point has coordinates: ({}, {}, {})",
                borrowed_point.x, another_borrow.y, point.z);

    // The immutable references are no longer used for the rest of the code so
    // it is possible to reborrow with a mutable reference.
    let mutable_borrow = &mut point;

    // Change data via mutable reference
    mutable_borrow.x = 5;
    mutable_borrow.y = 2;
    mutable_borrow.z = 1;

    // Error! Can't borrow `point` as immutable because it's currently
    // borrowed as mutable.
    // let y = &point.y;
    // TODO ^ Try uncommenting this line

    // Error! Can't print because `println!` takes an immutable reference.
    // 这里进行了不可变借用后，后面就不能进行可变借用
    println!("Point Z coordinate is {}", point.z);
    // TODO ^ Try uncommenting this line

    // Ok! Mutable references can be passed as immutable to `println!`
    // 如果这里不使用 可变借用 ，那么可变借用已在前面被销毁了，所以前面的不可变借用也没有问题
    println!("Point has coordinates: ({}, {}, {})",
                mutable_borrow.x, mutable_borrow.y, mutable_borrow.z);

    // The mutable reference is no longer used for the rest of the code so it
    // is possible to reborrow
    let new_borrowed_point = &point;
    println!("Point now has coordinates: ({}, {}, {})",
             new_borrowed_point.x, new_borrowed_point.y, new_borrowed_point.z);
    // 也就是说，不论是引用是可变还是不可变，后面没有了其他的使用的时候，是可以自由进行的
}